﻿using System;
using System.Collections.Generic;
using System.Linq;
using UtilityToolsCollect.ExtensionMethodLibrary;

namespace SearchInFiles.Lib.Search
{
    public class StandardSearcher : SearcherAbstract
    {
        private static readonly char[] separator = { '\u0020', '\u3000', '\u00A0' };
        private const char ExcludeMark = '!';
        private bool IsAllMatch;
        public string[] existence;
        public string[] exclude;

        public StandardSearcher(string searchParameters, bool IsAllMatch, bool IsCompleteMatch, int FrontLength, int AfterLength) : base(FrontLength, AfterLength)
        {
            string[] SearchParameters;
            this.IsAllMatch = IsAllMatch;
            if (IsCompleteMatch)
                SearchParameters = [searchParameters];
            else
                SearchParameters = searchParameters.Split(separator, StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries);
            IEnumerable<IGrouping<bool, string>> g = SearchParameters.GroupBy(p => p.StartsWith(ExcludeMark));
            exclude = g.FirstOrDefault(p => p.Key)?.Select(p => p.TrimStart(ExcludeMark)).ToArray() ?? new string[0];
            existence = g.FirstOrDefault(p => !p.Key)?.Select(p =>p).ToArray() ?? new string[0];
        }
        public override bool Search(SearchRequest Request)
        {
            bool Result = false;
            if (string.IsNullOrEmpty(Request.Value) || existence.Length < 1)
                return Result;

            foreach (string item in exclude)
            {
                if (SundaySearch.SundayIndexOf(Request.Value, item, out _))
                    return Result;
            }
            bool IsHit;
            List<SearchResult> CurrentSearchResult = [];
            foreach (string item in existence)
            {
                IsHit = false;
                foreach (int s in SundaySearch.SundaySearchAllIndexs(Request.Value, item))
                {
                    IsHit = true;
                    CurrentSearchResult.Add(new SearchResult(s,item, SearchResult.GetPartialContext(Request.Value, item, s, FrontLength, AfterLength), Request.RequestElement, Request.SourceInfo));
                    if (!Result) Result = true;
                }
                if(IsAllMatch && !IsHit)
                    return false;
            }
            foreach (SearchResult result in CurrentSearchResult)
                Results.Add(result);
            return Result;
        }

        
    }
}
